package com.oa.dao.impl;

import com.oa.common.base.Page;
import com.oa.common.base.Pageable;
import com.oa.common.eums.EntityStatus;
import com.oa.common.interfaces.PreFilter;
import com.oa.dao.BaseDaoImpl;
import com.oa.dao.PositionDao;
import com.oa.dao.PreFilters;
import com.oa.entities.Position;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Repository
public class PositionDaoImpl extends BaseDaoImpl<Long,Position> implements PositionDao {

    @Override
    protected void loadClassType() {
        setType(Position.class);
    }

    @Override
    public Page<Position> findPage(Pageable pageable, String key) {
        StringBuilder builder= new StringBuilder();
        builder.append("select position from Position position");
        if (!StringUtils.isEmpty(key)){
            builder.append(" join position.parent parent");
        }
        builder.append(" where position.status=:status");
        if (!StringUtils.isEmpty(key)){
            builder.append(" and (position.name like :key or parent.name like :key");
        }
        Query query= getSession().createQuery(builder.toString())
                .setParameter("status",EntityStatus.ENTITY_EABLE.getCode())
                .setFirstResult(pageable.getPageSize()*(pageable.getPageNumber()-1))
                .setMaxResults(pageable.getPageSize());
        if (!StringUtils.isEmpty(key)){
            key="%"+key+"%";
            query.setParameter("key",key);
        }
        List<Position> positionList= query.list();
        Criteria criteria= getCriteria();
        criteria.add(Restrictions.eq("status",EntityStatus.ENTITY_EABLE.getCode()));
        if (!StringUtils.isEmpty(key)){
            criteria.createAlias("parent","parent");
            criteria.add(Restrictions.or(
                    Restrictions.like("name",key),
                    Restrictions.like("parent.name",key)
            ));
        }
        long count= (long) criteria.setProjection(Projections.rowCount()).uniqueResult();
        return new Page(pageable,positionList,new Long(count).intValue());
    }

    @Override
    public Boolean validate(String name, Long id) {
        List<PreFilter> filters= new ArrayList<>();
        filters.add(PreFilters.eq(Position.PROP_STATUS,EntityStatus.ENTITY_EABLE.getCode()));
        filters.add(PreFilters.eq(Position.POSITION_NAME,name));
        if (id!=null){
            filters.add(PreFilters.noteq(Position.PROP_ID,id));
        }
        PreFilter[] fs= new PreFilter[filters.size()];
        return findUnqiue(filters.toArray(fs))!=null;
    }
}
